﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using Lib.Helper;
using MSIACCSL2.InventoryServices;
using MSIACCSL2.ItemServices;
using MSIACCSL2.PalletServices;
using MSIACCSL2.SubGroupServices;
using MSIACCSL2.WarehouseServices;
using WcfService1.DTO;

namespace MSIACCSL2.ViewModels
{
    public class SearchInventoryViewModel : ViewModelBase
    {
        private readonly InventoryServiceClient InventoryClient;
        private readonly ItemServicesClient ItemClient;
        private readonly SubGroupServiceClient SubgroupClient;
        private readonly WarehouseServicesClient WarehouseClient;
        public string Expression;
        public string SerialNumber;
        private ObservableCollection<InventoryDTO> _Inventories;
        private bool _IsBusy;
        private Visibility _gridVisibility;
        private InventoryDTO _inventory;
        private ObservableCollection<ItemDTO> _items;
        private ObservableCollection<PalletDTO> _pallets;
        private ObservableCollection<SubGroupDTO> _subgroups;
        private ObservableCollection<WarehouseDTO> _warehouses;
        private Visibility _gridItemVisibility;
        private Visibility _gridSubgroupVisibility;
        private WarehouseDTO _WarehouseSelected;
        private string _Pallet;

        public SearchInventoryViewModel()
        {
            if (! DesignerProperties.IsInDesignTool)
            {
                ItemClient = new ItemServicesClient();
                SubgroupClient = new SubGroupServiceClient();
                WarehouseClient = new WarehouseServicesClient();
                InventoryClient = new InventoryServiceClient();
                GetWarehouseList();
                Inventory = new InventoryDTO();
                Inventory.IsStock = true;
                GetSubGrouplist(null);
                GetItemList(null);
            }
        }

        public InventoryDTO Inventory
        {
            get { return _inventory; }
            internal set
            {
                _inventory = value;
                FirePropertyChanged("Inventory");
            }
        }

        public ObservableCollection<ItemDTO> Items
        {
            get { return _items; }
            private set
            {
                if (Items == value) return;
                _items = value;
                FirePropertyChanged("Items");
            }
        }

        public ObservableCollection<WarehouseDTO> Warehouses
        {
            get { return _warehouses; }
            private set
            {
                if (Warehouses == value) return;
                _warehouses = value;
                FirePropertyChanged("Warehouses");
            }
        }

        public ObservableCollection<PalletDTO> Pallets
        {
            get { return _pallets; }
            private set
            {
                if (Pallets == value) return;
                _pallets = value;
                FirePropertyChanged("Pallets");
            }
        }

        public ObservableCollection<SubGroupDTO> Subgroups
        {
            get { return _subgroups; }
            private set
            {
                if (Subgroups == value) return;
                _subgroups = value;
                FirePropertyChanged("Subgroups");
            }
        }

        public bool IsBusy
        {
            get { return _IsBusy; }
            internal set
            {
                _IsBusy = value;
                FirePropertyChanged("IsBusy");
            }
        }

        public WarehouseDTO WarehouseSelected
        {
            get { return _WarehouseSelected; }
            internal set
            {
                if (WarehouseSelected == value) return;
                _WarehouseSelected = value;
                FirePropertyChanged("WarehouseSelected");
            }
        }

        public String Pallet
        {
            get { return _Pallet; }
            set
            {
                if(Pallet == value) return;
                _Pallet = value;
                FirePropertyChanged("Pallet");
            }
        }

        public ObservableCollection<InventoryDTO> InventorySearchs
        {
            get { return _Inventories; }
            private set
            {
                if (InventorySearchs == value) return;
                _Inventories = value;
                FirePropertyChanged("InventorySearchs");
            }
        }

        public Visibility GridVisibility
        {
            get { return _gridVisibility; }
            private set
            {
                if (GridVisibility == value) return;
                _gridVisibility = value;
                FirePropertyChanged("GridVisibility");
            }
        }

        public Visibility GridItemVisibility
        {
            get { return _gridItemVisibility; }
            set
            {
                if (GridItemVisibility == value) return;
                _gridItemVisibility = value;
                FirePropertyChanged("GridItemVisibility");
            }
        }
        
         public Visibility GridSubgroupVisibility
        {
            get { return _gridSubgroupVisibility; }
            set
            {
                if (GridSubgroupVisibility == value) return;
                _gridSubgroupVisibility = value;
                FirePropertyChanged("GridSubgroupVisibility");
            }
        }


        public void SearchInventory(object param)
        {
            var criteria = new Dictionary<string, object>();
            Inventory = (InventoryDTO) param;
            foreach (PropertyInfo prop in Inventory.GetType().GetProperties())
            {
                if (prop.Name == "No" || prop.Name == "Group") continue;

                if (prop.PropertyType == typeof (Decimal))
                {
                    if ((Decimal) prop.GetValue(Inventory, null) == 0) continue;
                }

                if (prop.PropertyType == typeof (Int32))
                {
                    if ((Int32) prop.GetValue(Inventory, null) == 0) continue;
                }

                if (prop.PropertyType == typeof (Int64))
                {
                    if ((Int64) prop.GetValue(Inventory, null) == 0) continue;
                }

                if (prop.PropertyType == typeof (Double))
                {
                    if ((Double) prop.GetValue(Inventory, null) == 0) continue;
                }

                if (prop.PropertyType == typeof (String))
                {
                    if (String.IsNullOrEmpty((String) prop.GetValue(Inventory, null))) continue;
                }

                if (prop.PropertyType == typeof (DateTime))
                {
                    if (prop.GetValue(Inventory, null).ToString().Contains("0001")) continue;
                }

                if (prop.GetValue(Inventory, null) == null) continue;


                if (prop.PropertyType.Name.ToLower().Contains("dto"))
                {
                    foreach (PropertyInfo propertyInfo in prop.GetValue(Inventory, null).GetType().GetProperties())
                    {
                        if (propertyInfo.Name.ToLower().Contains("id") || propertyInfo.Name.ToLower().Contains("kode") ||
                            propertyInfo.Name.ToLower().Contains("serial"))
                        {
                            object val = propertyInfo.GetValue(prop.GetValue(Inventory, null), null);
                            if (val == null)
                            {
                                object obj = prop.GetValue(Inventory, null);
                                foreach (PropertyInfo objProp in obj.GetType().GetProperties())
                                {
                                    object val2 = objProp.GetValue(obj, null);
                                    if (val2 != null)
                                    {
                                        foreach (PropertyInfo objProp2 in val2.GetType().GetProperties())
                                        {
                                            if (objProp2.Name.ToLower().Contains("id") ||
                                                objProp2.Name.ToLower().Contains("kode") ||
                                                objProp2.Name.ToLower().Contains("serial"))
                                            {
                                                object val3 = objProp2.GetValue(val2, null);
                                                criteria.Add(prop.Name + "." + objProp.Name, val3);
                                                break;
                                            }
                                        }
                                        break;
                                    }
                                }

                                break;
                            }
                            else
                            {
                                criteria.Add(prop.Name, val);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    criteria.Add(prop.Name, prop.GetValue(Inventory, null));
                }
            }

            if (WarehouseSelected != null)
                criteria.Add("InventoryWarehouses", WarehouseSelected.KodeWarehouse);

            if (! String.IsNullOrEmpty(Pallet))
                criteria.Add("KodePallet",Pallet);


            InventorySearch(criteria, Expression);
        }

        private void InventorySearch(Dictionary<String, Object> criteria, string expression)
        {
            IsBusy = true;
            InventoryClient.GetInventoryByCriteriaFullCompleted += InventoryClient_GetInventoryByCriteriaFullCompleted;
            InventoryClient.GetInventoryByCriteriaFullAsync(criteria, expression, 1);
        }

        private void InventoryClient_GetInventoryByCriteriaFullCompleted(object sender,
                                                                         GetInventoryByCriteriaFullCompletedEventArgs e)
        {
            InventoryClient.GetInventoryByCriteriaFullCompleted -= InventoryClient_GetInventoryByCriteriaFullCompleted;
            InventorySearchs = e.Result;
            IsBusy = false;
            if (e.Result.Count == 0) MessageBox.Show("Data tidak ada!");
            InventorySearchs.Add(new InventoryDTO());
            GridVisibility = Visibility.Visible;
        }


        public void GetItemList(Object param)
        {
            ItemClient.GetAllItemCompleted += ItemClient_GetAllItemCompleted;
            ItemClient.GetAllItemAsync();
        }

        void ItemClient_GetAllItemCompleted(object sender, GetAllItemCompletedEventArgs e)
        {
            ItemClient.GetAllItemCompleted -= ItemClient_GetAllItemCompleted;
            Items = e.Result;
        }

        public void GetSubGrouplist(Object param)
        {
            SubgroupClient.GetAllSubGroupCompleted += SubgroupClient_GetAllSubGroupCompleted;
            SubgroupClient.GetAllSubGroupAsync();
        }

        void SubgroupClient_GetAllSubGroupCompleted(object sender, GetAllSubGroupCompletedEventArgs e)
        {
            SubgroupClient.GetAllSubGroupCompleted -= SubgroupClient_GetAllSubGroupCompleted;
            Subgroups = e.Result;
        }

      


        public void GetWarehouseList()
        {
            WarehouseClient.GetAllWarehouseCompleted += WarehouseClient_GetAllWarehouseCompleted;
            WarehouseClient.GetAllWarehouseAsync();
        }

        private void WarehouseClient_GetAllWarehouseCompleted(object sender, GetAllWarehouseCompletedEventArgs e)
        {
            WarehouseClient.GetAllWarehouseCompleted -= WarehouseClient_GetAllWarehouseCompleted;
            Warehouses = e.Result;
        }
     
    }
}